﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YJKPresentation.Utils.Generics;

namespace YJKPresentation.Utils
{
	public class Common
	{
		public static double MMToFeet(double val)
		{
			return val / 304.8;
		}

		public static double FeetToMM(double val)
		{
			return val * 304.8;
		}

		public static int Chr2AscII(string character)
		{
			if (character.Length == 1)
			{
				return (int)new ASCIIEncoding().GetBytes(character)[0];
			}
			throw new Exception("Character is not valid.");
		}

		public static string AscII2Chr(int asciiCode)
		{
			if (asciiCode >= 0 && asciiCode <= 255)
			{
				ASCIIEncoding asciiencoding = new ASCIIEncoding();
				byte[] bytes = new byte[]
				{
					(byte)asciiCode
				};
				return asciiencoding.GetString(bytes);
			}
			throw new Exception("ASCII Code is not valid.");
		}

		public static void UpdateModel(UIDocument uiDoc, bool autoJoin)
		{
			uiDoc.Document.Regenerate();
			if (autoJoin)
			{
				uiDoc.Document.AutoJoinElements();
			}
			uiDoc.RefreshActiveView();
		}

		public static List<XYZ> UniqueAndSortIntersectPoints(Curve curve, List<XYZ> intersectPoints)
		{
			Arc arc = curve as Arc;
			if (null != arc)
			{
				XYZ hyendPoint = arc.GetEndPoint(0);
				if (arc.Normal.Z < 0.0)
				{
					hyendPoint = arc.GetEndPoint(1);
				}
				intersectPoints.Sort(new AngleComparer(hyendPoint, arc.Center));
			}
			Line line = curve as Line;
			if (null != line)
			{
				XYZ hyendPoint2 = line.GetEndPoint(0);
				intersectPoints.Sort(new DistanceComparer(hyendPoint2));
			}
			IEnumerable<XYZ> enumerable = intersectPoints.Distinct(new Comparint<XYZ>((XYZ x, XYZ y) => x != null && y != null && x.DistanceTo(y) < 0.001));
			List<XYZ> list = new List<XYZ>();
			foreach (XYZ item in enumerable)
			{
				list.Add(item);
			}
			return list;
		}

		public static List<Level> GetSortLevels(Autodesk.Revit.DB.Document doc, double bottom, double top)
		{
			List<Level> list = new List<Level>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Level)).ToElements())
			{
				Level level = element as Level;
				double elevation = level.Elevation;
				if (elevation >= bottom && elevation <= top)
				{
					list.Add(level);
				}
			}
			list.Sort(new LevelComparer());
			return list;
		}

		public static List<Autodesk.Revit.DB.View> GetSortFloorViews(Autodesk.Revit.DB.Document doc, double bottom, double top)
		{
			List<Autodesk.Revit.DB.View> list = new List<Autodesk.Revit.DB.View>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Autodesk.Revit.DB.View)).ToElements())
			{
				if (element != null)
				{
					Autodesk.Revit.DB.View view = element as Autodesk.Revit.DB.View;
					if (view != null && (int)view.ViewType == 1 && view.GenLevel != null)
					{
						double elevation = view.GenLevel.Elevation;
						if (elevation >= bottom && elevation <= top)
						{
							list.Add(view);
						}
					}
				}
			}
			list.Sort(new ViewElevationComparer());
			return list;
		}

		public static double GetViewHeight(Autodesk.Revit.DB.Document doc, Autodesk.Revit.DB.View view)
		{
			double result = Common.MMToFeet(4000.0);
			List<Autodesk.Revit.DB.View> sortFloorViews = Common.GetSortFloorViews(doc, double.MinValue, double.MaxValue);
			int num = sortFloorViews.FindIndex((Autodesk.Revit.DB.View s) => s.Id.Compare(view.Id) == 0);
			if (num == -1 || num == sortFloorViews.Count - 1)
			{
				return result;
			}
			int i = num + 1;
			double elevation = sortFloorViews[num].GenLevel.Elevation;
			while (i < sortFloorViews.Count)
			{
				double elevation2 = sortFloorViews[i].GenLevel.Elevation;
				if (!Geometry.IsEqual(elevation2, elevation))
				{
					result = elevation2 - elevation;
					break;
				}
				i++;
			}
			return result;
		}

		private const double _eps = 1E-09;

		public class GridAndInfos
		{
			public GridAndInfos(int nummber, Grid grid)
			{
				this.m_Nummber = nummber;
				this.m_Grid = grid;
			}

			public static bool operator <(Common.GridAndInfos g1, Common.GridAndInfos g2)
			{
				return g1.m_Nummber < g2.m_Nummber;
			}

			public static bool operator >(Common.GridAndInfos g1, Common.GridAndInfos g2)
			{
				return g1.m_Nummber > g2.m_Nummber;
			}

			public static bool operator !=(Common.GridAndInfos g1, Common.GridAndInfos g2)
			{
				return g1.m_Nummber != g2.m_Nummber;
			}

			public static bool operator ==(Common.GridAndInfos g1, Common.GridAndInfos g2)
			{
				return g1.m_Nummber == g2.m_Nummber;
			}

			public override int GetHashCode()
			{
				return (this.m_Nummber ^ this.m_Nummber >> 16) * 352654597;
			}

			public bool Equals(Common.GridAndInfos other)
			{
				return !(other == null) && this.m_Grid == other.m_Grid && this.m_Nummber == other.m_Nummber;
			}

			public override bool Equals(object obj)
			{
				return this.Equals((Common.GridAndInfos)obj);
			}

			public int m_Nummber;

			public Grid m_Grid;
		}
	}
}
